using AutoMapper;
using Domain;
using ErrorCode;
using Infrastructure;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using RabbitTraceability.Api.Applications.Command;

namespace RabbitTraceability.Api.Applications.CommandHandler
{
    /// <summary>
    /// 添加保健信息命令处理程序
    /// </summary>
    public class AddHealthCareInfoCommandHandler : IRequestHandler<AddHealthCareInfoCommand, string>
    {
        /// <summary>
        /// 保健信息仓储
        /// </summary>
        private readonly IRepository<HealthCareInfo> _healthCareRepository;

        /// <summary>
        /// 溯源信息仓储，用于验证批次是否存在
        /// </summary>
        private readonly IRepository<TraceabilityInfo> _traceabilityRepository;
        
        /// <summary>
        /// 对象映射器
        /// </summary>
        private readonly IMapper _mapper;

        /// <summary>
        /// 日志记录器
        /// </summary>
        private readonly ILogger<AddHealthCareInfoCommandHandler> _logger;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="healthCareRepository">保健信息仓储</param>
        /// <param name="traceabilityRepository">溯源信息仓储</param>
        /// <param name="mapper">对象映射器</param>
        /// <param name="logger">日志记录器</param>
        public AddHealthCareInfoCommandHandler(
            IRepository<HealthCareInfo> healthCareRepository,
            IRepository<TraceabilityInfo> traceabilityRepository,
            IMapper mapper,
            ILogger<AddHealthCareInfoCommandHandler> logger)
        {
            _healthCareRepository = healthCareRepository;
            _traceabilityRepository = traceabilityRepository;
            _mapper = mapper;
            _logger = logger;
        }

        /// <summary>
        /// 处理添加保健信息命令
        /// </summary>
        /// <param name="request">添加保健信息命令</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>新添加的保健信息ID</returns>
        public async Task<string> Handle(AddHealthCareInfoCommand request, CancellationToken cancellationToken)
        {
            _logger.LogInformation("开始处理添加保健信息请求，批次：{ProductionBatch}", request.ProductionBatch);

            try
            {
                // 验证关联的生产批次是否存在
                var existingTraceability = await _traceabilityRepository.GetAll()
                    .AnyAsync(t => t.ProductionBatch == request.ProductionBatch && !t.IsDeleted, cancellationToken);
                
                if (!existingTraceability)
                {
                    _logger.LogWarning("关联的生产批次不存在：{ProductionBatch}", request.ProductionBatch);
                    throw new ApiException(ResultCode.NotFound, $"关联的生产批次 '{request.ProductionBatch}' 不存在");
                }

                // 验证该批次是否已经存在保健信息
                var existingHealthCare = await _healthCareRepository.GetAll()
                    .AnyAsync(h => h.ProductionBatch == request.ProductionBatch && !h.IsDeleted, cancellationToken);
                
                if (existingHealthCare)
                {
                    _logger.LogWarning("该批次已存在保健信息：{ProductionBatch}", request.ProductionBatch);
                    throw new ApiException(ResultCode.DuplicateRecord, $"批次 '{request.ProductionBatch}' 已存在保健信息");
                }

                // 使用AutoMapper创建保健信息实体
                var healthCareInfo = _mapper.Map<HealthCareInfo>(request);

                // 添加到数据库
                await _healthCareRepository.Add(healthCareInfo);

                _logger.LogInformation("成功添加保健信息，保健编号：{HealthCareId}，批次：{ProductionBatch}", 
                    healthCareInfo.HealthCareId, request.ProductionBatch);

                // 返回新创建的保健信息ID
                return healthCareInfo.HealthCareId;
            }
            catch (ApiException)
            {
                // 重新抛出API异常
                throw;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "添加保健信息时发生异常，批次：{ProductionBatch}", request.ProductionBatch);
                throw new ApiException(ResultCode.InternalServerError, "添加保健信息失败");
            }
        }
    }
} 